home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / alprog / alprog1.tut next >
Encoding:
Text File  |  1986-11-03  |  34.4 KB  |  928 lines

  1. ..       90 lines per page 
  2. ..       leave 6/12 lines for article headline
  3. ..    put cursor on ruler line & hit Ctrl-OF
  4. .. !------!----!----!----!----!----!----!----!-----
  5.  
  6.  
  7.  
  8.  
  9.  IBM Personal Computer Assembly Language Tutorial
  10.          Joshua Auerbach, Yale University
  11.  
  12.                Yale Computer Center
  13.                 175 Whitney Avenue
  14.                   P. O. Box 2112
  15.            New Haven, Connecticut 06520
  16.  
  17.  
  18. This talk is for people just getting started with 
  19. the PC MACRO Assembler.  Maybe you are just contem-
  20. plating doing some coding in assembler, maybe you 
  21. have tried it with mixed success.  If you are here 
  22. to get aimed in the right direction, to get off to 
  23. a good start with the assembler, then you have come 
  24. for the right reason.  I can't promise you'll get 
  25. what you want, but I'll do my best.
  26.  
  27. On the other hand, if you have already turned out 
  28. some working assembler code, then this talk is 
  29. likely to be on the elementary side for you.  If 
  30. you want to review a few basics and have no where 
  31. else pressing to go, then by all means stay.
  32.  
  33. Why Learn Assembler?
  34. ___________________
  35.  
  36. The reasons for LEARNING assembler are not the same 
  37. as the reasons for USING it in a particular appli-
  38. cation.  But, we have to start with some of the 
  39. reasons for using it and then I think the reasons 
  40. for learning it will become clear.
  41.  
  42. First, let's dispose of a bad reason for using it.  
  43. Don't use it just because you think it is going to 
  44. execute faster.  A particular sequence of ordinary 
  45. bread-and-butter computations written in PASCAL, C, 
  46. FORTRAN, or compiled BASIC can do the job about as 
  47. fast as the same algorithm coded in assembler.  Of 
  48. course, interpretive BASIC is slower, but if you 
  49. have a BASIC application which runs too slow you 
  50. probably want to try compiling it before you think 
  51. too much about translating parts of it to another 
  52. language.
  53.  
  54. On the other hand, high level languages do tend to 
  55. isolate you from the machine.  That is both their 
  56. strength and their weakness.  Usually, when imple-
  57. mented on a micro, a high level language provides 
  58. an escape mechanism to the underlying operating 
  59. system or to the bare machine.  So, for example, 
  60. BASIC has its PEEK and POKE.  But, the route to the 
  61. bare machine is often a circuitous one, leading to 
  62. tricky programming which is hard to follow.
  63.  
  64. For those of us working on PC's connected to SHARE-
  65. class mainframes, we are generally concerned with 
  66. three interfaces:  the keyboard, the screen, and 
  67. the communication line or lines.  All three of 
  68. these entities raise machine dependent issues which 
  69. are imperfectly addressed by the underlying operat- 
  70. ing system or by high level languages.
  71.  
  72. Sometimes, the system or the language does too 
  73. little for you.  For example, with the asynch 
  74. adapter, the system provides no interrupt handler, 
  75. no buffer, and no flow control.  The application is 
  76. stuck with the responsibility for monitoring that 
  77. port and not missing any characters, then deciding 
  78. what to do with all errors.  BASIC does a 
  79. reasonable job on some of this, but that is only 
  80. BASIC.  Most other languages do less.
  81.  
  82. Sometimes, the system may do too much for you.  
  83. System support for the keyboard is an example.  At 
  84. the hardware level, all 83 keys on the keyboard 
  85. send unique codes when they are pressed, held down, 
  86. and released.  But, someone has decided that certain 
  87. keys, like Num Lock and Scroll Lock are going to do 
  88. certain things before the application even sees 
  89. them and can't therefore be used as ordinary keys.
  90.  
  91. Sometimes, the system does about the right amount 
  92. of stuff but does it less efficiently than it 
  93. should.  System support for the screen is in this 
  94. class.  If you use only the official interface to 
  95. the screen you sometimes slow your application down 
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. unacceptably.  I said before, don't use assembler 
  105. just to speed things up, but there I was talking 
  106. about mainline code, which generally can't be 
  107. speeded up much by assembler coding.  A critical 
  108. system interface is a different matter:  sometimes 
  109. we may have to use assembler to bypass a hopelessly 
  110. inefficient implementation.  We don't want to do 
  111. this if we can avoid it, but sometimes we can't.
  112.  
  113. Assembly language code can overcome these deficien-
  114. cies.  In some cases, you can also overcome these 
  115. deficiencies by judicious use of the escape valves 
  116. which your high level language provides.  In BASIC, 
  117. you can PEEK and POKE and INP and OUT your way 
  118. around a great many issues.  In other languages you 
  119. can issue system calls and interrupts and usually 
  120. manage, one way or other, to modify system memory.  
  121. Writing handlers to take real-time hardware inter-
  122. rupts from the keyboard or asynch port, though, is 
  123. still going to be a problem in most languages.  
  124. Some languages claim to let you do it but I have 
  125. yet to see an acceptably clean implementation done 
  126. that way.
  127.  
  128. The real reason while assembler is better than 
  129. "tricky POKEs" for writing machine-dependent code, 
  130. though, is the same reason why PASCAL is better 
  131. than assembler for writing a payroll package:  it 
  132. is easier to maintain. 
  133.  
  134. Let the high level language do what it does best, 
  135. but recognize that there are some things which are 
  136. best done in assembler code.  The assembler, unlike 
  137. the tricky POKE, can make judicious use of equates, 
  138. macros, labels, and appropriately placed comments 
  139. to show what is really going on in this machine-
  140. dependent realm where it thrives.
  141.  
  142. So, there are times when it becomes appropriate to 
  143. write in assembler; given that, if you are a 
  144. responsible programmer or manager, you will want to 
  145. be "assembler-literate" so you can decide when 
  146. assembler code should be written.
  147.  
  148. What do I mean by "assembler-literate?"  I don't 
  149. just mean understanding the 8086 architecture; I 
  150. think, even if you don't write much assembler code 
  151. yourself, you ought to understand the actual 
  152. process of turning out assembler code and the 
  153. various ways to incorporate it into an application.  
  154. You ought to be able to tell good assembler code 
  155. from bad, and appropriate assembler code from 
  156. inappropriate.
  157.  
  158. Steps to becoming ASSEMBLER-LITERATE
  159. ___________________________________
  160.  
  161. 1.  Learn the 8086 architecture and most of the     
  162.     instruction set.  Learn what you need to know 
  163.     and ignore what you don't.  Reading:  The 8086 
  164.     Primer by Stephen Morse, published by Hayden.  
  165.     You need to read only two chapters, the one on 
  166.     machine organization and the one on the 
  167.     instruction set.
  168.  
  169. 2.  Learn about a few simple DOS function calls.  
  170.     Know what services the operating system 
  171.     provides.  If appropriate, learn a little about 
  172.     other systems too.  It will aid portability 
  173.     later on.  Reading:  appendices D and E of the 
  174.     PC DOS manual.
  175.  
  176. 3.  Learn enough about the MACRO assembler and the 
  177.     LINKer to write some simple things that really 
  178.     work.  Here, too, the main thing is figuring 
  179.     out what you don't need to know.  Whatever you 
  180.     do, don't study the sample programs distributed 
  181.     with the assembler unless you have nothing 
  182.     better!
  183.  
  184. 4.  At the same time as you are learning the 
  185.     assembler itself, you will need to learn a few 
  186.     tools and concepts to properly combine your 
  187.     assembler code with the other things you do.  
  188.     If you plan to call assembler subroutines from 
  189.  
  190.  
  191.     a high level language, you will need to study 
  192.     the interface notes provided in your language     
  193.     manual.  Usually, this forms an appendix of     
  194.     some sort.  If you plan to package your     
  195.     assembler routines as .COM programs you will     
  196.     need to learn to do this.  You should also     
  197.     learn to use DEBUG.
  198.  
  199. 5.  Read the Technical Reference, but selectively.  
  200.     The most important things to know are the 
  201.     header comments in the BIOS listing.  Next, you 
  202.     will want to learn about the RS 232 port and 
  203.     maybe about the video adapters.
  204.  
  205. Notice that the key thing in all five phases is 
  206. being selective.  It is easy to conclude that there 
  207. is too much to learn unless you can throw away what 
  208. you don't need.  Most of the rest of this talk is 
  209. going to deal with this very important question of 
  210. what you need and don't need to learn in each 
  211. phase.  In some cases, I will have to leave you to 
  212. do almost all of the learning, in others, I will 
  213. teach a few salient points, enough, I hope, to get 
  214. you started.  I hope you understand that all I can 
  215. do in an hour is get you started on the way.
  216.  
  217. Phase 1: Learn the architecture and instruction set
  218. __________________________________________________
  219.  
  220. The Morse book might seem like a lot of book to buy 
  221. for just two really important chapters; other books 
  222. devote a lot more space to the instruction set and 
  223. give you a big beautiful reference page on each 
  224. instruction.  And, some of the other things in the 
  225. Morse book, although interesting, really aren't 
  226. very vital and are covered too sketchily to be of 
  227. any real help.  The reason I like the Morse book is 
  228. that you can just read it; it has a very conversa-
  229. tional style, it is very lucid, it tells you what 
  230. you really need to know, and a little bit more 
  231. which is by way of background; because nothing 
  232. really gets belabored too much, you can gracefully 
  233. forget the things you don't use.  And, I very much 
  234. recommend READING Morse rather than studying it.  
  235. Get the big picture at this point.
  236.  
  237. Now, you want to concentrate on those things which 
  238. are worth fixing in memory.  After you read Morse, 
  239. you should relate what you have learned to this 
  240. outline.
  241.  
  242. 1.  You want to fix in your mind the idea of the 
  243.     four segment registers CODE, DATA, STACK, and 
  244.     EXTRA.  This part is pretty easy to grasp.  The 
  245.     8086 and the 8088 use 20 bit addresses for 
  246.     memory, meaning that they can address up to 1 
  247.     megabyte of memory.  But, the registers and the 
  248.     address fields in all the instructions are no 
  249.     more than 16 bits long.  So, how to address all 
  250.     of that memory?  Their solution is to put 
  251.     together two 16 bit quantities like this:
  252.  
  253.       calculation  SSSS0   ---- value in the 
  254.                                 relevant segment 
  255.                                 register SHL 4
  256.  
  257.       depicted in   AAAA   ---- apparent address 
  258.                                 from register or 
  259.                                 instruction
  260.       hexadecimal --------
  261.                    RRRRR   ---- real address placed 
  262.                                 on address bus
  263.  
  264.     In other words, any time memory is accessed, 
  265.     your program will supply a sixteen bit address.      
  266.     Another sixteen bit address is acquired from a     
  267.     segment register, left shifted four bits (one     
  268.     nibble) and added to it to form the real 
  269.     address.  You can control the values in the 
  270.     segment registers and thus access any part 
  271.     of memory you want.  But the segment registers     
  272.     are specialized:  one for code, one for most 
  273.     data accesses, one for the stack (which we'll 
  274.     mention again) and one "extra" one for 
  275.     additional data accesses.
  276.  
  277.     Most people, when they first learn about this 
  278.     addressing scheme become obsessed with convert-
  279.     ing everything to real 20 bit addresses.  After 
  280.     a while, though, you get used to thinking in 
  281.     segment/offset form.  You tend to get your 
  282.  
  283.  
  284.     segment registers set up at the beginning of 
  285.     the program, change them as little as possible, 
  286.     and think just in terms of symbolic locations 
  287.     in your program, as with any assembly language.
  288.  
  289.     EXAMPLE:
  290.  
  291.     MOV  AX,DATASEG
  292.     MOV  DS,AX         ;Set value of Data segment
  293.     ASSUME DS:DATASEG  ;Tell assembler DS is usable
  294.     .......
  295.     MOV  AX,PLACE      ;Access storage symbolically 
  296.                         by 16 bit address
  297.  
  298.     In the above example, the assembler knows that     
  299.     no special issues are involved because the     
  300.     machine generally uses the DS register to     
  301.     complete a normal data reference.
  302.  
  303.     If you had used ES instead of DS in the above 
  304.     example, the assembler would have known what to 
  305.     do, also.  In front of the MOV instruction 
  306.     which accessed the location PLACE, it would 
  307.     have placed the ES segment prefix.  This would 
  308.     tell the machine that ES should be used, 
  309.     instead of DS, to complete the address.
  310.  
  311.     Some conventions make it especially easy to 
  312.     forget about segment registers.  For example, 
  313.     any program of the COM type gets control with 
  314.     all four segment registers containing the same 
  315.     value.  This program executes in a simplified 
  316.     64K address space.  You can go outside this 
  317.     address space if you want but you don't have to.
  318.  
  319. 2.  You will want to learn what other registers are 
  320.     available and learn their personalities:
  321.  
  322.     ' AX and DX are general purpose registers.    
  323.       They become special only when accessing 
  324.       machine and system interfaces.
  325.  
  326.     ' CX is a general purpose register which is 
  327.       slightly specialized for counting.
  328.  
  329.     ' BX is a general purpose register which is 
  330.       slightly specialized for forming base-
  331.       displacement addresses.
  332.  
  333.     ' AX-DX can be divided in half, forming AH, AL, 
  334.       BH, BL, CH, CL, DH, DL.
  335.  
  336.     ' SI and DI are strictly 16 bit.  They can be 
  337.       used to form indexed addresses (like BX) and 
  338.       they are also used to point to strings.
  339.  
  340.     ' SP is hardly ever manipulated.  It is there 
  341.       to provide a stack.
  342.  
  343.     ' BP is a manipulable cousin to SP.  Use it to 
  344.       access data which has been pushed onto the 
  345.       stack.
  346.  
  347.     ' Most sixteen bit operations are legal (even 
  348.       if unusual) when performed in SI, DI, SP, or 
  349.       BP.
  350.  
  351. 3.  You will want to learn the classifications of 
  352.     operations available WITHOUT getting hung up in 
  353.     the details of how 8086 opcodes are constructed.
  354.     8086 opcodes are complex.  Fortunately, the 
  355.     assembler opcodes used to assemble them are 
  356.     simple.  When you read a book like Morse, you 
  357.     will learn some things which are worth knowing 
  358.     but NOT worth dwelling on.
  359.  
  360.     a.  8086 and 8088 instructions can be broken up 
  361.     into subfields and bits with names like R/M, 
  362.     MOD, S and W. These parts of the instruction 
  363.     modify the basic operation in such ways as 
  364.     whether it is 8 bit or 16 bit, and, if 16 bit, 
  365.     whether all 16 bits of the data are given; 
  366.     whether the instruction is register to 
  367.     register, register to memory, or memory to 
  368.     register; for operands which are registers, 
  369.     which register; for operands which are memory, 
  370.     what base and index registers should be used in 
  371.     finding the data.
  372.  
  373.     b.  Also, some instructions are actually repre-
  374.  
  375.  
  376.     sented by several different machine opcodes 
  377.     depending on whether they deal with immediate 
  378.     data or not, or on other issues, and there are 
  379.     some expedited forms which assume that one of 
  380.     the arguments is the most commonly used ope-
  381.     rand, like AX in the case of arithmetic.
  382.     
  383.     There is no point in memorizing this detail; 
  384.     just distill the bottom line, which is, what 
  385.     kinds of operand combinations EXIST in the 
  386.     instruction set and what kinds don't.  If you 
  387.     ask the assembler to ADD two things and they 
  388.     are things for which there is a legal ADD 
  389.     instruction somewhere in the instruction set, 
  390.     the assembler will find the right instruction 
  391.     and fill in all the modifier fields for you.
  392.  
  393.     I guess if you memorized all the opcode con-
  394.     struction rules you might have a crack at being 
  395.     able to disassemble hex dumps by eye, like you 
  396.     may have learned to do somewhat with 370 assem-
  397.     bler.  I submit to you that this feat, if ever 
  398.     mastered by anyone, would be in the same class 
  399.     as playing the "Minute Waltz" in a minute; a 
  400.     curiosity only.
  401.  
  402.     Here is the basic matrix you should remember:
  403.  
  404.           Two operands:          One operand:
  405.           R      <-- M                R
  406.           M      <-- R                M
  407.           R      <-- R                S *
  408.           R or M <-- I
  409.           R or M <-- S  *
  410.           S      <-- R_M  *
  411.  
  412.     * -- data moving instructions
  413.                  (MOV, PUSH, POP) only
  414.     S -- segment register (CS, DS, ES, SS)
  415.     R -- ordinary register (AX, BX, CX, DX, SI, DI, 
  416.            BP, SP, AH, AL, BH, BL, CH, CL, DH, DL)
  417.     M -- one of the following
  418.                pure address
  419.                [BX]+offset
  420.                [BP]+offset
  421.                any of the above indexed by SI
  422.                any of the first three indexed by DI
  423.  
  424. 4.  Of course, you want to learn the operations 
  425.     themselves.  As I've suggested, you want to 
  426.     learn the op codes as the assembler presents 
  427.     them, not as the CPU machine language presents 
  428.     them.  So, even though there are many MOV op 
  429.     codes you don't need to learn them.  Basically, 
  430.     here is the instruction set:
  431.  
  432.     a.  Ordinary two operand instructions.  These 
  433.     instructions perform an operation and leave the 
  434.     result in place of one of the operands.  They 
  435.     are
  436.  
  437.     1)  ADD and ADC -- addition, with or without 
  438.     including a carry from a previous addition
  439.  
  440.     2)  SUB and SBB -- subtraction, with or without 
  441.     including a borrow from a previous subtraction
  442.  
  443.     3)  CMP -- compare.  It is useful to think of 
  444.     this as a subtraction with the answer thrown 
  445.     away and neither operand actually changed
  446.  
  447.     4)  AND, OR, XOR -- typical boolean operations
  448.  
  449.     5)  TEST -- like an AND, except the answer is 
  450.     thrown away and neither operand is changed.
  451.  
  452.     6)  MOV -- move data from source to target
  453.  
  454.     7)  LDS, LES, LEA -- some specialized forms of 
  455.     MOV with side effects
  456.  
  457.     b.  Ordinary one operand instructions.  These 
  458.     can take any of the operand forms described 
  459.     above.  Usually, the perform the operation and 
  460.     leave the result in the stated place:
  461.  
  462.     1)  INC -- increment contents
  463.  
  464.     2)  DEC -- decrement contents
  465.  
  466.     3)  NEG -- twos complement
  467.  
  468.     4)  NOT -- ones complement
  469.  
  470.     5)  PUSH -- value goes on stack (operand 
  471.                 location itself unchanged)
  472.  
  473.     6)  POP -- value taken from stack, replaces 
  474.                current value
  475.  
  476.     c.  Now you touch on some instructions which do 
  477.     not follow the general operand rules but which 
  478.     require the use of certain registers.  The 
  479.     important ones are
  480.  
  481.     1)  The multiply and divide instructions
  482.  
  483.     2)  The "adjust" instructions which help in 
  484.         performing arithmetic on ASCII or packed 
  485.         decimal data
  486.  
  487.     3)  The shift and rotate instructions.  These 
  488.         have a restriction on the second operand:  
  489.         it must either be the immediate value 1 or 
  490.         the contents of the CL register.
  491.  
  492.     4)  IN and OUT which send or receive data from 
  493.         one of the 1024 hardware ports.
  494.  
  495.     5)  CBW and CWD -- convert byte to word or word 
  496.                     to doubleword by sign extension
  497.  
  498.     d.  Flow of control instructions.  These 
  499.     deserve study in themselves and we will discuss 
  500.     them a little more.  They include
  501.  
  502.     1)  CALL, RET -- call and return
  503.  
  504.     2)  INT, IRET -- interrupt and return-from-
  505.                        interrupt
  506.  
  507.     3)  JMP -- jump or "branch"
  508.  
  509.     4)  LOOP, LOOPNZ, LOOPZ -- special (and useful) 
  510.         instructions which implement a counted loop 
  511.         similar to the 370 BCT instruction
  512.  
  513.     5)  various conditional jump instructions
  514.  
  515.     e.  String instructions.  These implement a 
  516.     limited storage-to-storage instruction subset 
  517.     and are quite powerful.  All of them have the 
  518.     property that
  519.  
  520.     1)  The source of data is described by the 
  521.         combination DS and SI.
  522.  
  523.     2)  The destination of data is described by the 
  524.         combination ES and DI.
  525.  
  526.     3)  As part of the operation, the SI and/or DI 
  527.     register(s) is(are) incremented or decremented 
  528.     so the operation can be repeated.
  529.  
  530.     They include
  531.  
  532.       1)  CMPSB/CMPSW -- compare byte or word
  533.  
  534.       2)  LODSB/LODSW -- load byte or word 
  535.                          into AL or AX
  536.  
  537.       3)  STOSB/STOSW -- store byte or word
  538.                          from AL or AX
  539.  
  540.       4)  MOVSB/MOVSW -- move byte or word
  541.  
  542.       5)  SCASB/SCASW -- compare byte or word with 
  543.                          contents of AL or AX
  544.  
  545.       6)  REP/REPE/REPNE -- a prefix which can be 
  546.         combined with any of the above instructions 
  547.         to make them execute repeatedly across a 
  548.         string of data whose length is held in CX.
  549.  
  550.     f.  Flag instructions: CLI, STI, CLD, STD, CLC, 
  551.     STC.  These can set or clear the interrupt 
  552.     (enabled) direction (for string operations) or 
  553.     carry flags.
  554.  
  555.     The addressing summary and the instruction 
  556.     summary given above masks a lot of annoying 
  557.     little exceptions.  For example, you can't 
  558.  
  559.  
  560.     POP CS, and although the R <-- M form of LES 
  561.     is legal, the M <-- R form isn't etc. etc.  My 
  562.     advice is
  563.  
  564.     a.  Go for the general rules
  565.  
  566.     b.  Don't try to memorize the exceptions
  567.  
  568.     c.  Rely on common sense and the assembler to 
  569.     teach you about exceptions over time.  A lot of 
  570.     the exceptions cover things you wouldn't want 
  571.     to do anyway.
  572.  
  573. 5.  A few instructions are rich enough and useful 
  574.     enough to warrent careful study.  Here are a 
  575.     few final study guidelines:
  576.  
  577.     a.  It is well worth the time learning to use 
  578.     the string instruction set effectively.  Among 
  579.     the most useful are
  580.  
  581.     REP MOVSB           ;moves a string
  582.     REP STOSB           ;initializes memory
  583.     REPNE SCASB         ;look up occurance of 
  584.                            character in string
  585.     REPE CMPSB          ;compare two strings
  586.  
  587.     b.  Similarly, if you have never written for a 
  588.     stack machine before, you will need to exercise 
  589.     PUSH and POP and get very comfortable with them 
  590.     because they are going to be good friends.  If 
  591.     you are used to the 370, with lots of general 
  592.     purpose registers, you may find yourself 
  593.     feeling cramped at first, with many fewer 
  594.     registers and many instructions having register 
  595.     restrictions.  But, you have a hidden ally:  
  596.     you need a register and you don't want to throw 
  597.     away what's in it?  Just PUSH it, and when you 
  598.     are done, POP it back.  This can lead to abuse.  
  599.     Never have more than two "expedient" PUSHes in 
  600.     effect and never leave something PUSHed across 
  601.     a major header comment or for more than 15 
  602.     instructions or so.  An exception is the saving 
  603.     and restoring of registers at entrance to and 
  604.     exit from a subroutine; here, if the subroutine 
  605.     is long, you should probably PUSH everything 
  606.     which the caller may need saved, whether you 
  607.     will use the register or not, and POP it in 
  608.     reverse order at the end.
  609.  
  610.     Be aware that CALL and INT push return address 
  611.     information on the stack and RET and IRET pop 
  612.     it off.  It is a good idea to become familiar 
  613.     with the structure of the stack.
  614.  
  615.     c.  In practice, to invoke system services you 
  616.     will use the INT instruction.  It is quite 
  617.     possible to use this instruction effectively in 
  618.     a cookbook fashion without knowing precisely 
  619.     how it works.
  620.  
  621.     d.  The transfer of control instructions (CALL, 
  622.     RET, JMP) deserve careful study to avoid 
  623.     confusion.  You will learn that these can be 
  624.     classified as follows:
  625.  
  626.     1)  all three have the capability of being 
  627.         either NEAR (CS register unchanged) 
  628.         or FAR (CS register changed)
  629.  
  630.     2)  JMPs and CALLs can be DIRECT (target is 
  631.         assembled into instruction) or INDIRECT 
  632.         (target fetched from memory or register)
  633.  
  634.     3)  if NEAR and DIRECT, a JMP can be SHORT 
  635.         (less than 128 bytes away) or LONG
  636.  
  637.     In general, the third issue is not worth 
  638.     worrying about.  On a forward jump which is 
  639.     clearly VERY short, you can tell the assembler 
  640.     it is short and save one byte of code:
  641.  
  642.                JMP SHORT  CLOSEBY
  643.  
  644.     On a backward jump, the assembler can figure it 
  645.     out for you.  On a forward jump of dubious 
  646.     length, let the assembler default to a LONG 
  647.     form; at worst you waste one byte.
  648.     Also leave the assembler to worry about how the 
  649.  
  650.  
  651.  
  652.     target address is to be represented, in 
  653.     absolute form or relative form.
  654.  
  655.     e.  The conditional jump set can be confusing 
  656.     when studied apart from the assembler, but you 
  657.     do need to get a feeling for it.  The inter-
  658.     actions of the sign, carry, and overflow flags 
  659.     can get your mind stuttering pretty fast if you 
  660.     worry about it too much.  What is boils down 
  661.     to, though, is
  662.  
  663.     JZ        means what it says
  664.     JNZ       means what it says
  665.     JG reater this means "if the SIGNED 
  666.                             difference is positive"
  667.     JA bove   this means "if the UNSIGNED 
  668.                             difference is positive"
  669.     JL ess    this means "if the SIGNED 
  670.                             difference is negative"
  671.     JB elow   this means "if the UNSIGNED 
  672.                             difference is negative"
  673.     JC arry   assembles the same as JB; it's an 
  674.                                    aesthetic choice
  675.  
  676.     You should understand that all conditional 
  677.     jumps are inherently DIRECT, NEAR, and "short"; 
  678.     the "short" part means that they can't go more 
  679.     than 128 bytes in either direction.  Again, 
  680.     this is something you could easily imagine to 
  681.     be more of a problem than it is.  I follow this 
  682.     simple approach:
  683.  
  684.     1)  When taking an abnormal exit from a block 
  685.       of code, I always use an unconditional jump.  
  686.       Who knows how far you are going to end up 
  687.       jumping by the time the program is finished.  
  688.       For example, I wouldn't code this:
  689.  
  690.         TEST   AL,IDIBIT   ;Is the idiot bit on?
  691.         JNZ    OYVEY       ;Yes.  Go to cleanup
  692.  
  693.       Rather, I would probably code this:
  694.  
  695.         TEST   AL,IDIBIT   ;Is the idiot bit on?
  696.         JZ     NOIDIOCY    ;No.  I am saved.
  697.         JMP    OYVEY       ;Yes.  What can we say...
  698.       NOIDIOCY:
  699.  
  700.       The latter, of course, is a jump around a 
  701.       jump.  Some would say it is evil, but I 
  702.       submit it is hard to avoid in this language.
  703.  
  704.     2)  Otherwise, within a block of code, I use 
  705.       conditional jumps freely.  If the block 
  706.       eventually grows so long that the assembler 
  707.       starts complaining that my conditional jumps 
  708.       are too long, I
  709.       a)  consider reorganizing the block but
  710.  
  711.       b)  also consider changing some conditional 
  712.         jumps to their opposite and use the "jump 
  713.         around a jump" approach as shown above.
  714.  
  715.       Enough about specific instructions!
  716.  
  717. 6.  Finally, in order to use the assembler 
  718.     effectively, you need to know the default rules 
  719.     for which segment registers are used to 
  720.     complete addresses in which situations.
  721.  
  722.     a.  CS is used to complete an address which is 
  723.     the target of a NEAR DIRECT jump.  On an NEAR 
  724.     INDIRECT jump, DS is used to fetch the address 
  725.     from memory but then CS is used to complete the 
  726.     address thus fetched.  On FAR jumps, of course, 
  727.     CS is itself altered.  The instruction counter 
  728.     is always implicitly pointing in the code 
  729.     segment.
  730.  
  731.     b.  SS is used to complete an address if BP is 
  732.     used in its formation.  Otherwise, DS is always 
  733.     used to complete a data address.
  734.  
  735.     c.  On the string instructions, the target is 
  736.     always formed from ES and DI.  The source is 
  737.     normally formed from DS and SI.  If there is a 
  738.     segment prefix, it overrides the source not the 
  739.     target.
  740.  
  741.  
  742.  
  743. Learning about DOS
  744. _________________
  745.  
  746. I think the best way to learn about DOS internals 
  747. is to read the technical appendices in the manual.  
  748. These are not as complete as we might wish, but 
  749. they really aren't bad; I certainly have learned a 
  750. lot from them.  What you don't learn from them you 
  751. might eventually learn via judicious disassembly of 
  752. parts of DOS, but that shouldn't really be necessary.
  753.  
  754. From reading the technical appendices, you learn 
  755. that interrupts 20H through 27H are used to 
  756. communicate with DOS.  Mostly, you will use 
  757. interrupt 21H, the DOS function manager.
  758.  
  759. The function manager implements a great many 
  760. services.  You request the individual services by 
  761. means of a function code in the AH register.  For 
  762. example, by putting a nine in the AH register and 
  763. issuing interrupt 21H you tell DOS to print a 
  764. message on the console screen.
  765.  
  766. Usually, but by no means always, the DX register is 
  767. used to pass data for the service being requested.  
  768. For example, on the print message service just 
  769. mentioned, you would put the 16 bit address of the 
  770. message in the DX register.  The DS register is 
  771. also implicitly part of this argument, in keeping 
  772. with the universal segmentation rules.
  773.  
  774. In understanding DOS functions, it is useful to 
  775. understand some history and also some of the 
  776. philosophy of MS-DOS with regard to portability.  
  777. Generally, you will find, once you read the 
  778. technical information on DOS and also the IBM 
  779. technical reference, you will know more than one 
  780. way to do almost anything.  Which is best?  For 
  781. example, to do asynch adapter I/O, you can use the 
  782. DOS calls (pretty incomplete), you can use BIOS, or 
  783. you can go directly to the hardware.  The same 
  784. thing is true for most of the other primitive I/O 
  785. (keyboard or screen) although DOS is more likely to 
  786. give you added value in these areas.  When it comes 
  787. to file I/O, DOS itself offers more than one 
  788. interface.  For example, there are four calls which 
  789. read data from a file.
  790.  
  791. The way to decide rationally among the alternatives 
  792. is by understanding the tradeoffs of functionality 
  793. versus portability.  Three kinds of portability 
  794. need to be considered: machine portability, oper-
  795. ating system portability (for example, the ability 
  796. to assemble and run code under CP/M 86) and DOS 
  797. version portability (the ability for a program to 
  798. run under older versions of DOS>.
  799.  
  800. Most of the functions originally offered in DOS 1.0 
  801. were direct descendents of CP/M functions; there is 
  802. even a compatibility interface so that programs 
  803. which have been translated instruction for instruc-
  804. tion from 8080 assembler to 8086 assembler might 
  805. have a reasonable chance of running if they use 
  806. only the core CP/M function set.  Among the most 
  807. generally useful in this original compatibility set 
  808. are
  809.  
  810. 09 - print a full message on the screen
  811. 0A - get a console input line with full DOS editing
  812. 0F - open a file
  813. 10 - close a file (really needed only when writing)
  814. 11 - find first file matching a pattern
  815. 12 - find next file matching a pattern
  816. 13 - erase a file
  817. 16 - create a file
  818. 17 - rename a file
  819. 1A - set disk transfer address
  820.  
  821. The next set provide no function above what you can 
  822. get with BIOS calls or more specialized DOS calls.  
  823. However, they are preferable to BIOS calls when 
  824. portability is an issue.
  825.  
  826. 00 - terminate execution
  827. 01 - read keyboard character
  828. 02 - write screen character
  829. 03 - read COM port character
  830. 04 - write COM port character
  831. 05 - print a character
  832. 06 - read keyboard or write screen with no editing
  833.  
  834.  
  835.  
  836. The standard file I/O calls are inferior to the 
  837. specialized DOS calls but have the advantage of 
  838. making the program easier to port to CP/M style 
  839. systems.  Thus they are worth mentioning:
  840.  
  841. 14 - sequential read from file
  842. 15 - sequential write to file
  843. 21 - random read from file
  844. 22 - random write to file
  845. 23 - determine file size
  846. 24 - set random record
  847.  
  848. In addition to the CP/M compatible services, DOS 
  849. also offers some specialized services which have 
  850. been available in all releases of DOS.  These 
  851. include
  852.  
  853. 27    - multi-record random read.
  854. 28    - multi-record random write.
  855. 29    - parse filename
  856. 2A-2D - get and set date and time
  857.  
  858. All of the calls mentioned above which have any-
  859. thing to do with files make use of a data area 
  860. called the "FILE CONTROL BLOCK" (FCB).  The FCB is 
  861. anywhere from 33 to 37 bytes long depending on how 
  862. it is used.  You are responsible for creating an 
  863. FCB and filling in the first 12 bytes, which 
  864. contain a drive code, a file name, and an 
  865. extension.
  866.  
  867. When you open the FCB, the system fills in the next 
  868. 20 bytes, which includes a logical record length.  
  869. The initial lrecl is always 128 bytes, to achieve 
  870. CP/M compatibility.  The system also provides other 
  871. useful information such as the file size.
  872.  
  873. After you have opened the FCB, you can change the 
  874. logical record length.  If you do this, your prog-
  875. ram is no longer CP/M compatible, but that doesn't 
  876. make it a bad thing to do.  DOS documentation 
  877. suggests you use a logical record length of one for 
  878. maximum flexibility.  This is usually a good 
  879. recommendation.
  880.  
  881. To perform actual I/O to a file, you eventually 
  882. need to fill in byte 33 or possibly bytes 34-37 of 
  883. the FCB.  Here you supply information about the 
  884. record you are interested in reading or writing.  
  885. For the most part, this part of the interface is 
  886. compatible with CP/M.
  887.  
  888. In general, you do not need to (and should not) 
  889. modify other parts of the FCB.
  890.  
  891. The FCB is pretty well described in appendix E of 
  892. the DOS manual.
  893.  
  894. Beginning with DOS 2.0, there is a whole new system 
  895. of calls for managing files which don't require 
  896. that you build an FCB at all.  These calls are 
  897. quite incompatible with CP/M and also mean that 
  898. your program cannot run under older releases of 
  899. DOS.  However, these calls are very nice and easy 
  900. to use.  They have these characteristics
  901.  
  902. 1.  To open, create, delete, or rename a file, you 
  903.     need only a character string representing its 
  904.     name.
  905.  
  906. 2.  The open and create calls return a 16 bit value 
  907.     which is simply placed in the BX register on 
  908.     subsequent calls to refer to the file.
  909.  
  910. 3.  There is not a separate call required to 
  911.     specify the data buffer.
  912.  
  913. 4.  Any number of bytes can be transfered on a 
  914.     single call; no data area must be manipulated 
  915.     to do this.
  916.  
  917. The "new" DOS calls also include comprehensive 
  918. functions to manipulate the new chained directory 
  919. structure and to allocate and free memory.
  920.  
  921.   [We'll conclude this superb article next month]
  922.   [when Joshua Auerbach tells us about          ]
  923.   [    Learning the assembler                   ]
  924.   [    What about subroutines?                  ]
  925.   [    Learning about BIOS and the hardware     ]
  926.   [    A final example                       Ed.]
  927.  
  928.